#include <cstdio>
#include <unistd.h>
#include<iostream>
#include <string>
#include"ChatClient.h"
#include"Parser.h"
#include"Message2.pb.h"
using namespace wjc;
using namespace Log;
using namespace tutorial;

void ChatClient::onMessage(TcpClient& client, const ConnectionPtr& conn, BufferPtr& buff, Timestamp tm) {
    auto messagePtr = Parser::parse(buff.get());
    if (messagePtr) {
        std::shared_ptr<Message2> msgPtr = std::static_pointer_cast<Message2>(messagePtr);
        switch (msgPtr->type()) {
        case Message2::ALIVE: {
            conn->receiveHeart();
            break;
        }
        case Message2::TEXT: {
            //queueOut.push(msg);
            std::string str = msgPtr->name() + ": " + msgPtr->data();
            LOG_INFO << str;
            printf("%s", str.c_str());
            break;
        }
        case Message2::IDENTITY: {
            conn->setIdentity(msgPtr->data());
            break;
        }
        }
    }
}

void ChatClient::onConnection(TcpClient& client, const ConnectionPtr& conn) {
    std::string msg = "";
    switch (conn->getState()) {
    case Connection::kConnected:
        LOG_INFO << "kConnected";
        break;
    case Connection::kDisconnected:
        LOG_INFO << "kDisconnected";
        msg = "you leave the room!\n";
        printf("%s", msg.c_str());
        break;
    default:
        break;
    }
}

ChatClient::ChatClient(const net::InetAddress& serverAddr, const std::string& name) :client(serverAddr, name) {
    client.setMessageCallback(std::bind(&ChatClient::onMessage, this, std::ref(client), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    client.setConnectionCallback(std::bind(&ChatClient::onConnection, this, std::ref(client), std::placeholders::_1));
    client.connect();
}

void ChatClient::start() {
    std::string msg;
    while (std::getline(std::cin, msg)) {
        if (msg == "\\exit") {
            //client.connection()->close();
            //std::this_thread::sleep_for(std::chrono::seconds(100));
            break;
        }

        std::shared_ptr<Message2> msgPtr = std::make_shared<Message2>();
        msgPtr->set_type(Message2::TEXT);
        auto conn = client.connection();
        if (conn)
            msgPtr->set_name(conn->getIdentity());
        else
            break;
        msg += "\n";
        msgPtr->set_data(msg.c_str());
        auto msgPtrCast = std::dynamic_pointer_cast<google::protobuf::Message>(msgPtr);
        client.sendMsg(msgPtrCast);
    }
}

//int main()
//{
//    uint16_t port = 2070;
//    net::InetAddress serverAddr(port);
//    std::string name = "CharClient";
//
//    pause();
//    printf("hello from corenet!\n");
//    return 0;
//}